package cn.com.libertymutual.sp.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.core.des.Base64Encoder;
import com.google.common.collect.Maps;

import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.DateUtil;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sp.bean.TbSpUser;
import cn.com.libertymutual.sp.dao.UserDao;
import cn.com.libertymutual.sp.dto.ImageBase64Dto;
import cn.com.libertymutual.sp.service.api.FileUploadService;
import cn.com.libertymutual.sp.sftp.SFTP;
import cn.com.libertymutual.sys.nio.NioClient;

@Service
public class FileUploadServiceImpl implements FileUploadService {
	private Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private UserDao userDao;

	//@Autowired
	private SFTP sftp;
	@Autowired
	private NioClient nioClient;

	@Override
	public ServiceResult uploadFile(HttpServletRequest request, String userCode, MultipartFile file, String absolutePath, String relativePath)
			throws IOException {
		ServiceResult sr = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		if (file == null || file.isEmpty()) {
			sr.setResult("文件为空");
			return sr;
		}
		if (file.getSize() >= 1048576) {
			sr.setResult("文件大小不能超过1MB");
			return sr;
		}
		if (StringUtils.isBlank(userCode)) {
			sr.setResult("用户编码为空");
			return sr;
		}
		TbSpUser spUser = userDao.findByUserCode(userCode);
		if (spUser == null) {
			sr.setResult("用户为空");
			return sr;
		}
		String fileName = file.getOriginalFilename();
		File tempFile = new File(absolutePath, new Date().getTime() + String.valueOf(fileName));
		if (!tempFile.getParentFile().exists()) {
			tempFile.getParentFile().mkdir();
		}
		if (!tempFile.exists()) {
			tempFile.createNewFile();
		}
		file.transferTo(tempFile);
		// 文件base64码
		FileInputStream inputFile = new FileInputStream(tempFile);
		byte[] buffer = new byte[(int) tempFile.length()];
		inputFile.read(buffer);
		inputFile.close();
		String fileBase64Code = Base64Encoder.encode(buffer);
		// 绑定用户头像
		String dbUrl = relativePath + tempFile.getName();
		int updateNo = userDao.updateHeadUrlByUserCode(dbUrl, spUser.getUserCode());
		if (updateNo == 1) {
			// 重新获取用户信息
			spUser = userDao.findById(spUser.getId()).get();
			// 文件信息
			HashMap<String, Object> hashMap = Maps.newHashMap();
			hashMap.put("path", dbUrl);
			hashMap.put("fileName", tempFile.getName());
			hashMap.put("base64Code", fileBase64Code);
			hashMap.put("user", spUser);
			sr.setSuccess();
			sr.setResult(hashMap);
		}
		return sr;
	}

	public ServiceResult uploadImages(HttpServletRequest request, MultipartFile[] imgFiles, String absolutePath) {
		ServiceResult sr = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		MultipartFile file = null;
		for (int i = 0; i < imgFiles.length; ++i) {
			file = imgFiles[i];
			if (file.isEmpty()) {
				continue;
			}
			System.out.println("MultipartFile[]文件名称：" + file.getOriginalFilename());
		}
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		List<MultipartFile> myFiles = multipartRequest.getFiles("imgFiles");
		List<String> list = new ArrayList<String>();
		int number = 0;
		while (number < myFiles.size()) {
			file = myFiles.get(number);
			if (file.isEmpty()) {
				continue;
			}
			System.out.println("List<MultipartFile>文件名称：" + file.getOriginalFilename());
			try {
				String fileName = file.getOriginalFilename();
				// 获取文件的后缀名
				String suffixName = fileName.substring(fileName.lastIndexOf("."));
				if (!(suffixName.equals(".jpg") || suffixName.equals(".png") || suffixName.equals(".jpeg"))) {
					// 文件上传后的路径
					absolutePath = "/app/saleplatform/web/admin-sale/file/";
				}
				// 解决中文问题，liunx下中文路径，图片显示问题
				SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
				fileName = df.format(new Date()) + suffixName;
				File dest = new File(absolutePath + fileName);
				// 检测是否存在目录
				if (!dest.getParentFile().exists()) {
					dest.getParentFile().mkdirs();
				}
				file.transferTo(dest);
				// String src = absolutePath + fileName;
				// SFTP.SFTPupload(src);
				list.add(absolutePath + fileName);
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			number++;
		}
		if (number == myFiles.size()) {
			System.out.println("List<MultipartFile>上传文件个数：" + number);
			sr.setSuccess();
		}
		return sr;
	}

	public ServiceResult uploadImagesToSFTP(HttpServletRequest request, MultipartFile[] imgFiles, String rootPath, String folderName) {
		ServiceResult sr = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		if (CollectionUtils.sizeIsEmpty(imgFiles)) {
			sr.setAppFail("文件为空");
			return sr;
		}
		List<String> pathLists = new ArrayList<String>();
		int number = 0;
		while (number < imgFiles.length) {
			MultipartFile file = imgFiles[number];
			if (file.isEmpty()) {
				continue;
			}

			if (file.getSize() >= 1048576) {
				sr.setResult("文件大小不能超过1MB");
				return sr;
			}

			// rootPath = "F://image/";//本地测试地址
			try {
				// 目录名
				String folderPathName = rootPath + folderName;
				File folderFile = new File(folderPathName);
				if (!folderFile.exists()) {
					folderFile.mkdirs();
				}
				// 文件名
				String fileName = file.getOriginalFilename();
				// 文件类型
				String fileTypeName = fileName.substring(fileName.lastIndexOf(".") + 1);
				String oldFileName = fileName.substring(0, fileName.lastIndexOf("."));
				SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
				// 新文件名
				String newFileName = df.format(new Date()) + "-" + oldFileName + "." + fileTypeName;

				File newFile = new File(folderPathName, newFileName);
				// 检测是否存在
				if (!newFile.getParentFile().exists()) {
					newFile.getParentFile().mkdirs();
				}
				// 复制文件
				file.transferTo(newFile);

				// 传到FTP文件服务器
				nioClient.upload(newFile.getPath(), folderName);

				// 返回文件标准（去除../这样的符号）的绝地路径
				pathLists.add(newFile.getCanonicalPath());

			} catch (IllegalStateException e) {
				sr.setAppFail("上传异常：" + e.toString());
				e.printStackTrace();
				return sr;
			} catch (IOException e) {
				sr.setAppFail("上传异常：" + e.toString());
				e.printStackTrace();
				return sr;
			} catch (Exception e) {
				sr.setAppFail("上传异常：" + e.toString());
				e.printStackTrace();
				return sr;
			}
			number++;
		}
		if (number == imgFiles.length) {
			log.info("List<MultipartFile>上传文件个数：{}", number);
			sr.setSuccess();
			sr.setResult(pathLists);
		}
		return sr;
	}

	@Override
	public ServiceResult GenerateImage(HttpServletRequest request, String userCode, String imgStrCode, String absolutePath, String relativePath)
			throws IOException {
		ServiceResult sr = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		// 上传的图像数据为空
		if (StringUtils.isBlank(imgStrCode)) {
			sr.setResult("系统繁忙");
			return sr;
		}
		if (StringUtils.isBlank(userCode)) {
			sr.setResult("用户编码为空");
			return sr;
		}
		TbSpUser spUser = userDao.findByUserCode(userCode);
		if (spUser == null) {
			sr.setResult("用户为空");
			return sr;
		}

		// 去掉头部的data:image/png;base64,（注意有逗号）取base64码
		String code = imgStrCode.split(",")[1];
		byte[] codeBytes = Base64.decodeBase64(code);// BASE64Decoder.decode(imgStrCode);
		for (int i = 0; i < codeBytes.length; ++i) {
			if (codeBytes[i] < 0) {// 调整异常数据
				codeBytes[i] += 256;
			}
		}
		// 判断文件大小
		int equalIndex = code.indexOf("=");
		if (code.indexOf("=") > 0) {
			String str = code.substring(0, equalIndex);
			// 原来的字符流大小，单位为字节
			int strLength = str.length();
			// 计算后得到的文件流大小，单位为字节
			int fileLength = strLength - (strLength / 8) * 2;
			if (fileLength >= 1048576) {
				sr.setResult("文件大小不能超过1MB");
				return sr;
			}
		}

		String fileType = "jpg";
		// imgStrCode = ……
		// 
		String[] fileDataType = imgStrCode.split(";")[0].split(":")[1].split("\\/");
		String[] types = { "jpeg", "jpg", "png" };
		for (String t : types) {
			if (t.equals(fileDataType[1])) {
				fileType = t;
				break;
			}
		}

		File dirPath = new File(absolutePath);
		// 检查目录写权限
		// if (!dirPath.canWrite()) {
		// sr.setResult("上传目录没有写的权限");
		// return sr;
		// }

		if (!dirPath.exists()) {
			dirPath.mkdirs();
		}

		// 生成jpeg图片流
		String fromat = DateUtil.dateFromat(new Date().getTime(), DateUtil.DATE_TIME_PATTERN4LANG);
		String fileName = "headImg_" + fromat + "." + fileType;
		OutputStream out = new FileOutputStream(absolutePath + fileName);
		out.write(codeBytes);
		out.flush();
		out.close();

		// SFTP上传
		String src = absolutePath + fileName;

		sftp.SFTPupload(src);

		File tempFile = new File(absolutePath, fileName);
		if (tempFile.exists()) {
			// 更新用户头像数据库相对路径
			String dbUrl = relativePath + tempFile.getName();// upload/uploadHeadImg/1509708731735temp.jpeg
			int updateNo = userDao.updateHeadUrlByUserCode(dbUrl, spUser.getUserCode());
			if (updateNo == 1) {
				spUser.setHeadUrl(dbUrl);
				// 文件信息
				HashMap<String, Object> hashMap = Maps.newHashMap();
				hashMap.put("path", dbUrl);
				hashMap.put("fileName", fileName);
				hashMap.put("base64Code", imgStrCode);
				hashMap.put("user", spUser);
				sr.setSuccess();
				sr.setResult(hashMap);
			}
		}
		return sr;
	}

	@Override
	public ServiceResult uploadImagesByCode(HttpServletRequest request, ImageBase64Dto imageBase64Dto, String absolutePath, String relativePath)
			throws IOException {
		ServiceResult sr = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		// 上传的图像数据为空
		if (CollectionUtils.isEmpty(imageBase64Dto.getImages())) {
			sr.setResult("系统繁忙");
			return sr;
		}
		List<String> imgPath = new ArrayList<>();
		int num = 0;
		while (num < imageBase64Dto.getImages().size()) {
			String imgStrCode = imageBase64Dto.getImages().get(num);
			// 去掉头部的data:image/png;base64,（注意有逗号）取base64码
			String code = imgStrCode.split(",")[1];
			byte[] codeBytes = Base64.decodeBase64(code);// BASE64Decoder.decode(imgStrCode);
			for (int j = 0; j < codeBytes.length; j++) {
				if (codeBytes[j] < 0) {// 调整异常数据
					codeBytes[j] += 256;
				}
			}
			String fileType = "jpg";
			// imgStrCode = ……
			String[] fileDataType = imgStrCode.split(";")[0].split(":")[1].split("\\/");
			String[] types = { "jpeg", "jpg", "png" };
			for (String t : types) {
				if (t.equals(fileDataType[1])) {
					fileType = t;
					break;
				}
			}
			// 目录检查并创建
			File dirPath = new File(absolutePath);
			if (!dirPath.exists()) {
				dirPath.mkdirs();
			}
			// 生成jpeg图片流
			String fromat = DateUtil.dateFromat(new Date().getTime(), DateUtil.DATE_TIME_PATTERN4LANG);
			String fileName = "report_case_" + num + "_" + fromat + "." + fileType;
			OutputStream out = new FileOutputStream(absolutePath + fileName);
			out.write(codeBytes);
			out.flush();
			out.close();

			// SFTP上传
			String src = absolutePath + fileName;

			sftp.SFTPupload(src);

			File tempFile = new File(absolutePath, fileName);
			if (tempFile.exists()) {
				// 相对路径
				String dbUrl = relativePath + tempFile.getName();// upload/uploadHeadImg/1509708731735temp.jpeg
				imgPath.add(dbUrl);
			}
			num++;
		}
		if (num == imageBase64Dto.getImages().size()) {
			// 文件路径信息
			sr.setSuccess();
			sr.setResult(imgPath);
		}
		return sr;
	}

	@Override
	public File getFile(String path, String fileName, HttpServletRequest request) {
		File tempFile = new File(path, fileName);
		if (tempFile.exists()) {
			return tempFile;
		}
		return null;
	}

	@Override
	public String saveFile(MultipartFile file, String uploadHeadimgPathUsers, HttpServletRequest request) {
		// 判断文件是否为空
		if (!file.isEmpty()) {
			try {
				// 文件保存路径
				String filePath = request.getSession().getServletContext().getRealPath(uploadHeadimgPathUsers) + file.getOriginalFilename();
				// 转存文件
				File temp = new File(filePath);
				file.transferTo(temp);
				return request.getContextPath() + "/output.pc?fileName=" + temp.getName();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/** 
	  * 将文件转成base64 字符串 
	  * @param path文件路径 
	  * @return  *  
	  * @throws Exception 
	  */

	public String encodeBase64File(String path) throws Exception {
		File file = new File(path);
		;
		FileInputStream inputFile = new FileInputStream(file);
		byte[] buffer = new byte[(int) file.length()];
		inputFile.read(buffer);
		inputFile.close();
		return Base64Encoder.encode(buffer);
	}

	/**Remarks: 根据项目获取头像上传目录<br>
	 * Version：1.0<br>
	 * Author：AoYi<br>
	 * DateTime：2017年10月10日上午12:09:34<br>
	 * Project：liberty_sale_plat<br>
	 * @param request
	 * @return
	 */
	public static String getUploadPath(HttpServletRequest request) {
		return System.getProperty("user.dir") + "/app/saleplatform/web/sticsale/upload/userHeadImg/users";
	}

	public static void main(String[] args) {
		String path = System.getProperty("user.dir") + "/app/saleplatform/web/sticsale/upload/userHeadImg/users";
		path = path.replaceAll("\\/", "\\");
		System.out.println("path=" + path);
		File dirPath = new File(path);
		if (!dirPath.exists()) {
			dirPath.mkdirs();
		}
	}
}
